1. /* simdcvdc.cpp by K.Tsuru */
  2. // function ID = 414 BRADIX
  3. /***************************************************************************
  4. SInteger class
  5. BRADIX ---> DRADIX fast radix conversion
  6. Provides the divide radix conversion.
  7. In special case it is equivalent to the binary splitting method. See below.
  8. [Argorithm]
  9. step 1
  10. For a SInteger number u[N-1]...u[1]u[0] it converts into SLong by 'd' figures
  11. independently and puts into SLong r[].
  12. Let B = BRADIX and assume that N=p*d. Using arithmetic of SLong(radix = DRADIX)
  13. it evaluates
  14. r[0] <-- u[d-1]*B^(d-1)+...+u[1]*B+u[0]
  15. r[1] <-- u[2*d-1]*B^(d-1)+...+u[d+1]*B+u[d]
  16. ...........................................
  17. r[k] <-- u[(k+1)*d-1]*B^(d-1)+...+u[k*d+1]*B+u[kd]
  18. ...........................................
  19. r[p-1]<-- u[d*p-1]*B^(d-1)+...+u[(p-1)*d+1]*B+u[(p-1)*d]
  20. =u[N-1]*B^(d-1)+...+u[N-d+1]*B+u[N-d].
  21. In each polynomial the Horner's method can be used.
  22. step 2
  23. It converts into SLong binding two figures of r[].
  24. It assumes that p = 2^n, if not chooses 'n' to satisfy 2^(n-1)< p <2^n and
  25. fills the residual upper part of r[] with zeros.
  26. A. Starting with Q = B^d,
  27. B.
  28. B-1 r[0] <-- r[1]*Q + r[0]
  29. r[1] <-- r[3]*Q + r[2]
  30. .....................
  31. r[k] <-- r[2*k+1]*Q+r[2*k]
  32. ....................,
  33. r[p/2-1] <-- r[p-1]*Q+r[p-2]
  34. B-2 p <-- p/2
  35. B-3 When p = 1, go to step C. If not let Q *= Q and return to step B-1.
  36. C. The required result is put in r[0].
  37. If the FFT multiplication is used the computational complexity has an order
  38. of N(logN)^2.
  39. [Notice]
  40. 1)For the step 1 the paralell computing can be applied.
  41. 2)Taking d=1 the above method is equivalent to the binary splitting one.
  42. ******************************************************************************/
  43. #ifndef SN_H
  44. #include "sn.h"
  45. #endif
  46. SLong SInteger::DConvToDec() const {
  47. int N = (int)Head()+1, rsz, z;
  48. if(!Sign(414)) return 0.0;
  49. if((uint)N <= 2u*minArraySize) return NConvToDec();
  50. int j, k, p, q;
  51. double w;
  52. w = FFTMinSize(DEC_INT)*(double)DFIGURES/log10((double)BRADIX); // ver.2.17
  53. p = (int)w-1;
  54. rsz = N/p;
  55. if(N % p) rsz++;
  56. SLong* r = new SLong[rsz];
  57. w = (double)N*log10((double)BRADIX)/(double)DFIGURES + 1.0; // ver.2.17
  58. //figures in DRADIX
  59. //An overflow error will be detected by FigureAlloc().
  60. uint dec_fig = min(ceilpow2((uint)w), r[0].MaxSize());
  61. /*
  62. It allocates the memory of r[0],r[1] and R whose required size is previously known.
  63. This takes into the unreducible size mode.
  64. */
  65. r[0].FigureAlloc(dec_fig, -1);
  66. if(rsz > 1) r[1].FigureAlloc(dec_fig/4u, -1);
  67. SLong R(r[0].Type(), dec_fig/2u, BRADIX);
  68. const fType* pf = ReadFigures();
  69. /*
  70. step 1 :
  71. About the computational complexity the ratio of this step to step 2 is 1/6 to 1/5.
  72. Then optimizing this step does not improve so much.
  73. */
  74. for(k = 0; k < rsz - 1 ; k++){ //pass if rsz == 1
  75. q = (k+1)*p - 1;
  76. r[k].SetLong(pf[q]); // Horner's method
  77. for(j = q - 1; j >= k*p; j--){
  78. r[k] = LsMult(r[k], BRADIX);
  79. r[k].LsAdd(pf[j]);
  80. // r[k] = r[k]*R + figure(j);
  81. }
  82. }
  83. //upper residual figures k = rsz - 1
  84. r[k].SetLong(pf[N-1]); // r[k] = figure(N-1);
  85. for(j = N-2; j >= k*p; j--){ //When rsz = 1 and k = 0, this is executed.
  86. r[k] = LsMult(r[k], BRADIX);
  87. r[k].LsAdd(pf[j]);
  88. }
  89. if(rsz == 1) goto Ret;
  90. /*
  91. step 2 : It converts into SDLong binding two figures of r[].
  92. It is fast because the FFT multiplication is used.
  93. If much memory can be used it will be better that the table of R^n is made on
  94. hard disk and reads it.
  95. */
  96. // Here rsz >= 2.
  97. z = ceilpow2(rsz);
  98. R = Lpow(R, p); // = BRADIX^p
  99. while(z){
  100. for(j = 0; j < z ; j += 2){
  101. if(j <= rsz-2) r[j/2] = r[j+1]*R + r[j];
  102. else if(j == rsz-1) r[j/2] = r[j];
  103. else r[j/2].SetZero(); // j >= rsz
  104. }
  105. z /= 2;
  106. #if PoorMemory // Upper parts of r[] occupy small memory, then "Out of memory" will not occur.
  107. for(j = z; j < s; j++) r[j].SizeZero();
  108. for(j = 2; j < z; j++) r[j].ReduceSize();
  109. if(z == 2) r[1].ReduceSize();
  110. #endif
  111. if(z == 1) break; //do not evaluate last R *= R;
  112. R *= R;
  113. }
  114. Ret:
  115. //The last result is put in r[0].
  116. R.SizeZero();
  117. R = r[0];
  118. delete[] r;
  119. if(Sign() < 0) R.ChangeSign();
  120. return R;
  121. }

simdcvdc.cpp : last modifiled at 2017/03/17 11:10:47(4,239 bytes)
created at 2016/04/25 14:53:17
The creation time of this html file is 2017/10/25 11:09:45 (Wed Oct 25 11:09:45 2017).